You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Consolidate PutInOperationName, PatchInOperationName, and DeleteInOperationName into @azure-tools/typespec-client-generator-core/use-correct-verb, as agreed in the review discussion.
This PR absorbs the PATCH promotion #5665 and replaces the already-merged PUT rule from #5457. Both open promotion histories are preserved by consolidation merge commit d12175650. Following the combined-migration presentation in #5663, #5556, #5294, and #5423, further review of these three SDK naming checks belongs here. Superseding #5665 does not imply CI or review approval; its branch and review history remain intact.
One HTTP service-endpoint traversal, one common SDK-name resolver, and one warning per offending concrete endpoint. Prefix matching remains case-insensitive; GET, POST, and HEAD are not checked.
getLibraryName(..., AllScopes) honors unscoped @clientName, exact names, and the supported friendly-name fallback. Language-specific overrides and explicit OpenAPI operation IDs do not replace the common name.
Diagnostics target original operations. Both ARM and data-plane service endpoints are supported without requiring provider metadata. Client-only declarations outside HTTP services are not checked.
The rule does not mutate namespaces, select emitters, project API versions, reconstruct historical renamed names, or import AutoRest.
The single client-sdk registration is explicitly disabled by default. Data-plane/resource-manager rulesets and C# defaults are unchanged.
Separate rule implementations, their single-consumer traversal helper, and duplicate per-verb documentation/test files are replaced by one canonical rule, documentation page, and parameterized behavior suite. The unnecessary package-level AutoRest import isolation test has been removed; the canonical rule suite owns behavior coverage.
Compatibility and migration
use-create-for-put is replaced, not retained as a second public alias. Update linter configuration and #suppress diagnostic codes to use-correct-verb. Anyone who had explicitly enabled PUT naming guidance will now opt into PATCH and DELETE checks as well. The proposed PATCH/DELETE rule names are likewise replaced.
Renaming an already-shipped SDK method can be breaking. The diagnostic and documentation retain this warning; approved compatibility exceptions can use operation-level suppression with a justification. This change does not itself rename generated methods.
The package has one feature Chronus entry describing the consolidated behavior and configuration migration, plus a separate rulesets registration entry. Generated linter references, the ARM migration table, and TCGC documentation knowledge use the combined name.
Consolidation and immutable source provenance
Check
Recorded lintdiff source
Native promotion incorporated
PUT
#5455, feature/lintdiff-put-in-operation-name, recorded source 99cead8b6584f5cc1b0db3bf7810b53aa0eb221b
Merged #5457; implementation already present on main.
The lintdiff sources, fixtures, snapshots, and migration evidence are not changed. The PUT source SHA is recorded historical provenance; its GitHub availability is not newly claimed.
The approved native SDK-name adaptation remains intentional: a valid unscoped SDK override can fix an invalid authored name, or invalidate an otherwise compliant authored name. Serialized operationId underscore/group-prefix/missing-ID exemptions are not reproduced. Historical source corpus counts are not fresh combined-rule results, and exact Swagger diagnostic/count parity is not claimed. The naming policy remains in TCGC rather than introducing SDK dependencies into Azure Core or ARM.
Regression coverage
The canonical suite parameterizes all three verbs across accepted/rejected prefixes, casing, truncated names, common/scoped/exact/friendly names, explicit OpenAPI IDs, authored targets, group/underscore contrasts, response-code independence, multiple endpoints, and service-only selection.
Standard ARM create/patch/delete aliases are covered in both override directions. The published incorrect, correct, common-name, and suppression examples are read from the actual Markdown and compiled. An unfiltered mixed-verb regression requires three findings together, while allowing GET/POST/HEAD. Registration tests reject the old public names and keep the combined rule disabled by default.
Validation
After removing the package-isolation test, all TCGC rule suites: 262 tests passed in 8 files.
Documentation generation retains pre-existing missing-diagnostic-documentation and unused-parameter warnings on untouched APIs.
These are local results, not a claim that fresh GitHub CI or review has completed. No new full-package/full-monorepo test run, website build, or lintdiff corpus comparison is claimed.
Original DELETE promotion description before consolidation (historical)
Inspect DELETE operations selected from paths and x-ms-paths.
Read operationId, ignoring absent, empty or non-string values.
Ignore IDs without an underscore.
Accept the case-sensitive Delete prefix before the underscore or after a word-character group prefix.
Report a warning on the offending operationId when neither accepted form matches.
How the Swagger linter works
The Spectral function checks selected DELETE operation objects and applies serialized-ID regular expressions. It does not inspect SDK metadata or require ARM provider metadata. Its underscore/group-prefix exemptions can accept a Delete-prefixed group with a non-delete method, or ignore a standalone invalid method ID. Those serialization-dependent exemptions are intentionally not copied. Native endpoint selection also avoids warnings on declarations used only for client customization. The source migration evidence documents emitted-name overrides, historical version selection, one-sided projects and compilation failures rather than treating equal totals as proof of equivalence.
Immutable source commit: a0b5e8d9a9edee978219c2490c72eac7cc79845b; development GitHub review clean after two Balanced rounds on this final pushed commit.
Source worktree: C:\dev\worktrees\lintdiff-delete-in-operation-name; clean, no uncommitted source changes.
The source was assumed done for this promotion run and was not modified. It checks authored names on concrete HTTP service endpoints, DELETE only, with a case-insensitive delete prefix and warning targets on the original operation. Initial source commit 8af7a71258c41b8ca10950023c62cc4633bb24fc is historical; the reviewed source above additionally fixes the harness's stale coverage-kind assertion without changing production behavior.
Destination analysis
The agent selected @azure-tools/typespec-client-generator-core because the approved naming-family promotion contract governs common SDK method names. Existing use-create-for-put and supported getLibraryName(..., AllScopes) establish that ownership and implementation pattern. The new public name is use-delete-for-delete.
Both applicability and compiler/HTTP-only authored-name semantics make Azure Core a plausible authored-domain alternative. Core's use-standard-names already checks authored DELETE names in data-plane rulesets, but not the common SDK override domain. An SDK resolver must not introduce TCGC dependencies into Core or ARM. ARM fixture origin alone does not establish ARM-only semantics; this rule requires neither provider metadata nor ARM helpers in production. Existing TCGC get-operation-name is GET-specific and is not equivalent DELETE coverage.
How the promoted TypeSpec linter works
The root listener uses getAllHttpServices and checks concrete service operations with verb delete. A TCGC context created with { mutateNamespace: false } resolves the common SDK name using getLibraryName(context, operation, AllScopes). This honors unscoped client names, exact-name normalization and supported friendly-name fallback, independently of positive language-specific overrides and explicit OpenAPI operation IDs. No emitter or API-version projection is selected, and historical renamed names are not reconstructed.
The prefix remains case-insensitive, severity remains warning and each finding targets the original operation, including when an override supplies the displayed SDK name. Group names do not mask an invalid method name. The authorized adaptation changes only the authored-name domain to common SDK names; source selection, DELETE condition, prefix policy and diagnostic targets remain intact. There is no hand-rolled resolver, serialized-reference inference, namespace mutation or emitter coupling.
The client-sdk ruleset registers the new rule with plain false; ARM/data-plane rulesets and C# default rules are unchanged. Separate Chronus entries classify destination availability as feature and disabled-only ruleset registration as internal.
it("reports a customized standard ARM delete endpoint")
Actual source fixture contains a compliant delete and a violating remove despite its directory name. Replace legacy custom action/suppression with supported ArmResourceDeleteSync aliases; preserve prefix contrasts.
Actual source fixture contains a compliant delete and a violating remove despite its directory name. Replace legacy custom action/suppression with supported ArmResourceDeleteSync aliases; preserve prefix contrasts.
it("does not let a Delete-prefixed group mask an invalid method name")
Group prefix cannot hide invalid common method name.
N/A (documentation regression)
it("reports the published incorrect template alias")
Compile actual Markdown setup and incorrect ArmResourceDeleteSync alias; require one warning on remove.
N/A (documentation regression)
it("accepts the published correct template alias")
Compile actual Markdown correct alias with no target-rule diagnostics.
N/A (documentation regression)
it("accepts the published template client name override")
Compile actual Markdown common-name override with no target-rule diagnostics.
N/A (documentation regression)
it("accepts the published template suppression")
Compile actual Markdown suppression with the rule explicitly enabled through the compiler linter; require no diagnostics.
Additional native cases prove SDK override directions, language-specific and mixed names, exact names, friendly fallback, explicit-ID independence, original targets, multiple endpoint findings, non-DELETE controls, case-insensitive prefixes, source endpoint-selection regression, and a common client name on a supported standard ARM deletion alias. Framework-only import exclusion, ordinary inheritance/traversal, uninstantiated-template and suppression tests were not mechanically copied. No validator snapshots, fixtures or corpus payloads are included.
Migration evidence
See source migration.md for focused tests, representative services, full-corpus counts, one-sided project explanations, retained compile failures and uncertainty. Those counts describe the immutable authored-name source, not fresh SDK-domain equivalence or predicted impact. Promotion did not rerun the lintdiff harness or corpus.
Final emitter-free native rule suite: 28/28, including four tests that read and compile the actual published Markdown examples; target rule also passes all 28 cases in the full package run.
Required TCGC docs regeneration and explicit formatting/check of all four native/generated Markdown paths with NUL ignore override: exit 0; generated ignored rule page remains unstaged.
Following template-first skill update Require template-first lint documentation examples #5678 (created before this documentation update), the incorrect/correct, common-name override, and suppression examples use ArmResourceDeleteSync<Widget> instead of raw routes. The standalone shared setup includes all imports/usings. Incorrect remove produces exactly the target warning; correct delete, common-name override, and compiler-enabled suppression produce none. Existing generic HTTP behavior tests remain intact.
Separate feature/internal Chronus entries verified LF; plain pnpm chronus status: exit 0. Before commit, both change add attempts reported no changed package, so the documented fallback created only these two entries.
Full TCGC initial required run: 1660 passed, one 10000ms per-test timeout in arm client with sub clients, two existing skips; 1663 tests in 102 files, natural exit 1.
Single coordinator-granted diagnostic, exactly mise exec -- pnpm --filter @azure-tools/typespec-client-generator-core test --maxWorkers=1: 1661 passed, zero failures, same two skips and 1663 tests/102 files, natural exit 0. Same code, assertions, dependencies and 10000ms test/hook limits; no pool change. Timeout recovered with UNPROVEN original cause. The task-wide diagnostic allowance is exhausted (1/1); the scoped concurrency profile may persist for matching later package validation without granting another retry.
Latest full package run after template documentation/test changes: 1665 passed, two unchanged existing skips, 1667 total tests in 102 files, exit 0 using the same --maxWorkers=1 profile and unchanged test/hook timeouts. The four added tests account for the population increase.
Scoped TypeScript formatting/check and diff hygiene pass. The initial nine-file promotion patch previously passed read-only cached application check with an empty index; subsequent review/doc updates are scoped to the maintained rule documentation and native/rulesets tests.
Validation limitations
Required docs regeneration exits 0 with existing documentation warnings for unnecessary-emitter-option and unused API @param tags on untouched APIs; these unrelated warnings were retained, not repaired. The optional repository-wide wrapper was not warranted for this isolated rule and registration change. No local website/dependency-closure build was run; CI's Website job remains authoritative. The original full-suite timeout remains retained evidence, not an environmental diagnosis.
Promotion sync policy
The source remains immutable during promotion. A verified source-semantic gap blocks this PR and returns evidence to the owning queue, which alone may authorize its bounded source-repair cycle. Refresh native provenance incrementally only after a new clean reviewed source head; do not repair the source or silently alter its semantics in the promoted copy. The expressly approved common SDK naming adaptation is not source repair.
Review cleanup (October 19, 2026)
Renamed the groups to HTTP SDK names and standard ARM operations, preserving their separate SimpleTester and ARM/standalone setup. Removed the extra DELETE behavior file; focused package-level public-entry coverage retains the throwing AutoRest guard, now outside the PUT behavior suite as well. Removed redundant internal entries; feature and rulesets coverage remain.
Published in 50c4b74. Fresh focused validation: 68 tests passed, package production typecheck, root pnpm format, root pnpm lint, and diff hygiene passed. The full test TypeScript project retains pre-existing diagnostics (15 before, 15 after); the exact-head baseline comparison found no new diagnostics, accounting explicitly for moved tests and any removed duplicate fixture. This is not a claim that the full test TypeScript project is error-free or that pending CI has passed. These current file-layout/coverage statements supersede earlier descriptions of the removed test files; historical validation remains historical.
Follow the user-approved use-create-for-put pattern, keep client-sdk registration disabled, and remove the prior ARM introduction.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 8bf3420c-d859-4ac1-81e8-2081d1fded84
Replace the separate SDK verb naming registrations with @azure-tools/typespec-client-generator-core/use-correct-verb, disabled by default in the client-sdk ruleset.
Consolidate use-create-for-put, PATCH naming guidance, and DELETE naming guidance into the opt-in use-correct-verb lint rule. Common SDK method names must start with create for PUT, update for PATCH, and delete for DELETE, case-insensitively. Replace use-create-for-put in linter configuration and suppressions with use-correct-verb; enabling it also checks PATCH and DELETE. Renaming an already-shipped SDK method may be a breaking change.
✅ No notable package size changes compared to the base branch.
14 package(s) with no notable change
Package
Packed (base → head)
Δ Packed
Unpacked (base → head)
Δ Unpacked
@azure-tools/typespec-client-generator-core
248.83 KB → 248.39 KB
-450 B (-0.2%)
1.32 MB → 1.32 MB
-3.79 KB (-0.3%)
@azure-tools/typespec-azure-rulesets
5.60 KB → 5.54 KB
-66 B (-1.2%)
34.59 KB → 34.51 KB
-88 B (-0.2%)
@azure-tools/azure-http-specs
143.53 KB → 143.53 KB
—
1.20 MB → 1.20 MB
—
@azure-tools/typespec-autorest
87.87 KB → 87.87 KB
—
424.17 KB → 424.17 KB
—
@azure-tools/typespec-autorest-canonical
7.42 KB → 7.42 KB
—
26.00 KB → 26.00 KB
—
@azure-tools/typespec-azure-core
136.55 KB → 136.55 KB
—
733.30 KB → 733.30 KB
—
@azure-tools/typespec-azure-examples
80.15 KB → 80.15 KB
—
383.36 KB → 383.36 KB
—
@azure-tools/typespec-azure-portal-core
36.26 KB → 36.26 KB
—
242.62 KB → 242.62 KB
—
@azure-tools/typespec-azure-resource-manager
187.63 KB → 187.63 KB
—
1.13 MB → 1.13 MB
—
@azure-tools/typespec-go
263.76 KB → 263.76 KB
—
1.35 MB → 1.35 MB
—
@azure-tools/typespec-java
20.22 MB → 20.22 MB
—
22.51 MB → 22.51 MB
—
@azure-tools/typespec-metadata
15.91 KB → 15.91 KB
—
62.26 KB → 62.26 KB
—
@azure-tools/typespec-python
42.58 KB → 42.58 KB
—
166.02 KB → 166.02 KB
—
@azure-tools/typespec-ts
530.76 KB → 530.76 KB
—
2.67 MB → 2.67 MB
—
Packed = gzipped .tgz published to npm. Unpacked = total extracted size. 🆕 added, 🗑️ removed. Packages from the core/ submodule are not included. 🔴 grew · 🟢 shrank — only changes of at least 512 B and 0.5% are marked.
Add regression coverage for the disabled SDK naming rule registration and complete the suppression example.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 832854b7-de67-4f1f-8fe1-6a3e9897aeee
Because this rule explicitly applies to ARM services, it also needs a manual entry in the ARM reviewer guide at website/src/content/docs/docs/howtos/ARM/arm-rules.md. That guide requires a documentation link, LintDiff mapping, and impact for applicable rules (arm-rules.md:54-56) and already lists the analogous TCGC use-create-for-put rule at line 144; docs regeneration does not update this table.
## Why
The documentation in #5673 used raw HTTP routes for its
incorrect/correct examples even though supported `ArmResourceDeleteSync`
aliases demonstrate the same diagnostic contrast. The previous policy
required ARM templates only after selecting an ARM audience, allowing a
generic HTTP audience to bypass available templates.
The user requested a template-first requirement in
`/do-linter-development-task-one-by-one` and its related skills, with
this skill-only PR targeting the current branch,
`feature/lintdiff-migration-new`. The promotion documentation will be
updated separately after this PR is created.
## Changes
- Forward the template-first requirement in the queue's promotion
handoff.
- Require supported templates whenever they can demonstrate both
incorrect and correct behavior; inspect customization points before
choosing handwritten routes.
- Preserve audience-appropriate authoring and diagnostic contrast, and
require a documented template limitation for handwritten exceptions.
- Enforce the same requirement in promotion documentation/review and
documentation-example validation.
## Validation
Formatted and checked only the four changed skill Markdown files with
the existing Prettier installation; `git diff --check` passed. Reviewed
the complete four-file diff and existing cross-references. No helper,
package, dependency, submodule, or rule changes; no package builds or
tests are needed.
Copilot-Session: 832854b7-de67-4f1f-8fe1-6a3e9897aeee
Replace raw routes with ArmResourceDeleteSync aliases and validate the actual published examples, including compiler-enabled suppression.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 832854b7-de67-4f1f-8fe1-6a3e9897aeee
## Summary
- Treat a lint brief/PR description as the proposal under review, not a
reason to reject clear requests to simplify, revert, or consolidate it.
- Compare existing native mechanisms first; distinguish native
requirements and released compatibility from legacy parity and
complexity introduced by the proposal.
- Delete framework-only suppression/enablement tests without replacement
while retaining concrete rule-owned interactions, authored-node
deduplication, and meaningful regression preconditions.
- Remove bespoke per-rule Markdown parsers instead of moving them into
another suite. Validate published snippets through existing shared
tooling or recorded one-time execution, without claiming continuous
coverage from a one-time receipt.
- Keep actual policy/authorization gates, source immutability, required
validation, and released compatibility intact. Track replies separately
from satisfaction of review concerns.
## Evidence and rationale
This skill-only change follows a retrospective of recorded migration
feedback, not a new live-head review or a change to the underlying rule
PRs.
- [#5591 simplification
direction](#5591 (comment)),
[client-setup
question](#5591 (comment)),
and [model-tree
question](#5591 (comment)):
demonstrating differences from the current design does not independently
establish that its architecture is required.
- [#5551 consolidation
direction](#5551 (comment)):
assess extending the existing native rule and analyze actual
enablement/suppression consequences separately.
- Explicit requests for another maintainer's input, such as
[#5526](#5526 (comment))
and
[#5673](#5673 (comment)),
remain distinct decision dependencies.
The validation skill already discouraged framework-only unit tests, but
evidence-preservation wording could encourage relocating them. Promotion
still explicitly accommodated per-rule Markdown extraction. These
instructions now agree on removing unnecessary infrastructure without
discarding rule-owned behavior or honest published-example evidence.
## Scope
Only five existing skill Markdown files change: discovery,
implementation, validation, development, and promotion. No production
rules, package tests, dependencies, submodules, generated artifacts,
release entries, or CI configuration change. Two custom review/fix
skills stored outside this repository were updated locally in the same
task; they are not included in this PR.
Base: `feature/lintdiff-migration-new`, as explicitly requested.
## Validation
- Existing Prettier 3.9.5: focused Markdown format/check for the changed
files.
- `git diff --check`.
- Checked 78 concrete local Markdown references and heading anchors
across the five changed repository skills; template URL placeholders
were excluded.
- Reviewed the complete task diff and reconciled development/promotion
references with the shared validation guidance.
The root Prettier configuration could not load the unbuilt `core`
TypeSpec plugin. Formatting therefore used the existing Prettier
Markdown parser with the root style options and no custom plugins; no
dependency installation, submodule initialization, or build was
performed for this documentation-only change. Package/source lint and
test suites are not applicable under the skill-only
lightweight-validation policy. Normal CI is left enabled.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Merge Azure/typespec-azure main c13ceb4; retain both the migration-specific registration checks and main's opt-in redundant-summary check. No additional rule-policy changes.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
## Summary
Update five lint development/promotion skills to prevent the recurring
review feedback in the supplied 58-comment retrospective across 17
migration PRs. Target `feature/lintdiff-migration-new`, the branch
current when this work was requested.
| Review theme | Comments | Prevention |
| --- | ---: | --- |
| Redundant internal change entries | 28 | Inspect and reuse task-owned
unreleased feature/fix coverage before creating entries; preserve
genuinely needed coverage for other packages. |
| Multiple behavior suites for one public rule | 14 | Extend the
canonical suite, found by its imported rule object even when its
historical filename differs from the public name. |
| Repetitive test headings | 13 | Use file-scope cases or meaningful
scenario groups, preserving scoped setup rather than repeating the
rule/filename. |
| Private fixture APIs | 2 | Use supported public imports/decorators;
redesign or remove artificial private-only cases without changing
production scope. |
| Bespoke Markdown parser | 1 | Enforce the existing prohibition without
relocating the parser or losing distinct semantic/example evidence. |
These are five recurring lessons, not 58 independent design judgments:
55 comments explicitly disclose Copilot generation, and three have no
automation disclosure. Original report IDs 37-39 on #5591 and #5654
remain outside the selection.
## Changes
- `typespec-lint-validate`: define canonical suite ownership and
meaningful grouping; clarify genuine public-entry/package tests versus
duplicate rule execution under import guards; require public fixture
APIs.
- `typespec-lint-implement`: centralize unreleased change-entry
reconciliation and include the shared test policies in
implementation/final review.
- `lintdiff-rule-promote`: replace unconditional creation of a test
file/change entry with discovery and reuse; reconcile
acceptance-evidence and review instructions with the shared policies.
- `develop-lintdiff-rule`: reference the shared policies during test
planning and independent review; preserve migration/corpus requirements.
- `create-linter-rule`: apply the same guidance to scaffold cleanup,
existing-rule extensions, public fixtures, and changelog coverage.
## Evidence and boundaries
- [Changelog guidance, report
22](#5502 (comment))
- [Private APIs, report
23](#5502 (comment))
- [One behavior suite per rule, report
36](#5556 (comment))
- [Historical canonical filename, report
48](#5663 (comment))
- [Isolation-suite duplication, report
53](#5665 (comment))
- [Meaningful scenario grouping, report
55](#5673 (comment))
- [Markdown parser removal, report
33](#5551 (comment))
Keep independent utility tests, genuine package/registration evidence,
rule-owned diagnostic regressions, and actual published-example
validation. Keep separate rulesets-package internal coverage when
needed; do not delete all internal entries. Existing production
semantics, audience/enablement, source immutability, parity evidence,
and required validation remain unchanged.
Skills only: no generator, rule implementation/test, package,
dependency, release entry, or CI changes. The scaffolder's redundant
wrapper is explicitly handled by cleanup guidance; changing the
generator is a separate follow-up.
## Validation
- Scoped Prettier write/check on the five changed Markdown files, using
the repository's scalar formatting settings without optional plugins
because the configured TypeSpec plugin has no built output. No
dependencies or submodules were initialized for this documentation
update.
- Relative Markdown file/heading reference checks and full five-file
diff review.
- `git diff --check` and explicit staged-file scope verification.
No package builds, corpus runs, docs regeneration, or repository-wide
formatting/source linting are needed for this Markdown-only change.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Merge the PATCH promotion into #5673 and replace the separate rules with use-correct-verb. Preserve opt-in registration, common SDK name resolution, and combined regression coverage.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Yuchao Yan (msyyc)
changed the title
[Swagger Linter Migration] DeleteInOperationName -> use-delete-for-delete
[Swagger Linter Migration] PutInOperationName + PatchInOperationName + DeleteInOperationName -> use-correct-verb
Oct 20, 2026
The reason will be displayed to describe this comment to others. Learn more.
Remove Markdown reading, fence parsing/count assertions and the raw compiled documentation/suppression example.
This reintroduces the bespoke documentation parser and fence-count coupling that we already asked to remove across the migrations. Please delete it rather than moving it to a docs/integration suite. The suppression example should not become a test of compiler suppression machinery either.
Keep: Literal valid/invalid ARM aliases and common-name overrides in the canonical suite.
The reason will be displayed to describe this comment to others. Learn more.
Stop repeating every naming/metadata scenario for all three verbs; remove the 3-by-4 response-status matrix because the rule never inspects response status.
The shared naming algorithm is the same for PUT, PATCH and DELETE. Verify each verb-to-prefix mapping, but do not cross every common/scoped/friendly-name scenario with every verb. In particular, the production rule never reads the response status, so the 3 x 4 status-code cases do not need to exist.
Keep: A compact valid/invalid contract for each verb, mixed-verb dispatch, case/prefix boundaries, common/scoped precedence once, and representative ARM aliases.
The reason will be displayed to describe this comment to others. Learn more.
Please remove this shared-setup block. Rule documentation examples do not need to be complete, independently compilable specifications. The imports/usings, service namespace, common-types version and resource/provisioning-state declarations bury the SDK-name problem we want authors to see.
Keep short before/after operation snippets that make replace/modify/remove versus create*/update*/delete* obvious, and a small @clientName fix where useful. You can assume Widget and related resource types are defined. Keep standard ARM templates, but do not add a setup appendix or another shared preamble just to make the examples compile. Apply this focused-example style to the rest of the page too.
The reason will be displayed to describe this comment to others. Learn more.
Could this use the native operation listener instead of enumerating every service from root?
A parent service recursively includes its nested service's operations, and getAllHttpServices also returns the nested service separately. This currently produces two identical DELETE-prefix warnings for the single operation in:
Resolve the HTTP metadata per eligible operation and check it once through the existing linter traversal. Preserve the current service scope, including the no-explicit-service global fallback, and keep a focused regression expecting one diagnostic for the nested-service case.
Copilot-generated comment.
This branch has not been deployed
No deployments
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
engint:azure-specsRun integration tests against azure-rest-api-specslib:tcgcIssues for @azure-tools/typespec-client-generator-core librarylinterIssues related to linter rulesmeta:websiteTypeSpec.io updates
6 participants
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Consolidate PutInOperationName, PatchInOperationName, and DeleteInOperationName into
@azure-tools/typespec-client-generator-core/use-correct-verb, as agreed in the review discussion.This PR absorbs the PATCH promotion #5665 and replaces the already-merged PUT rule from #5457. Both open promotion histories are preserved by consolidation merge commit
d12175650. Following the combined-migration presentation in #5663, #5556, #5294, and #5423, further review of these three SDK naming checks belongs here. Superseding #5665 does not imply CI or review approval; its branch and review history remain intact.Combined behavior and legacy-rule mapping
use-create-for-put, merged #5457create.use-update-for-patch, #5665update.use-delete-for-delete, this PRdelete.getLibraryName(..., AllScopes)honors unscoped@clientName, exact names, and the supported friendly-name fallback. Language-specific overrides and explicit OpenAPI operation IDs do not replace the common name.client-sdkregistration is explicitly disabled by default. Data-plane/resource-manager rulesets and C# defaults are unchanged.Compatibility and migration
use-create-for-putis replaced, not retained as a second public alias. Update linter configuration and#suppressdiagnostic codes touse-correct-verb. Anyone who had explicitly enabled PUT naming guidance will now opt into PATCH and DELETE checks as well. The proposed PATCH/DELETE rule names are likewise replaced.Renaming an already-shipped SDK method can be breaking. The diagnostic and documentation retain this warning; approved compatibility exceptions can use operation-level suppression with a justification. This change does not itself rename generated methods.
The package has one feature Chronus entry describing the consolidated behavior and configuration migration, plus a separate rulesets registration entry. Generated linter references, the ARM migration table, and TCGC documentation knowledge use the combined name.
Consolidation and immutable source provenance
feature/lintdiff-put-in-operation-name, recorded source99cead8b6584f5cc1b0db3bf7810b53aa0eb221be009a4f53cc01eaa5c6a9ce85654fb1c4a8a6f4f8710828adc010571458235df8ff50e4019ce3107.a0b5e8d9a9edee978219c2490c72eac7cc79845b5fc361c18b79cfdf8460565fc7e3123669cc394d, before consolidation.The lintdiff sources, fixtures, snapshots, and migration evidence are not changed. The PUT source SHA is recorded historical provenance; its GitHub availability is not newly claimed.
The approved native SDK-name adaptation remains intentional: a valid unscoped SDK override can fix an invalid authored name, or invalidate an otherwise compliant authored name. Serialized
operationIdunderscore/group-prefix/missing-ID exemptions are not reproduced. Historical source corpus counts are not fresh combined-rule results, and exact Swagger diagnostic/count parity is not claimed. The naming policy remains in TCGC rather than introducing SDK dependencies into Azure Core or ARM.Regression coverage
The canonical suite parameterizes all three verbs across accepted/rejected prefixes, casing, truncated names, common/scoped/exact/friendly names, explicit OpenAPI IDs, authored targets, group/underscore contrasts, response-code independence, multiple endpoints, and service-only selection.
Standard ARM create/patch/delete aliases are covered in both override directions. The published incorrect, correct, common-name, and suppression examples are read from the actual Markdown and compiled. An unfiltered mixed-verb regression requires three findings together, while allowing GET/POST/HEAD. Registration tests reject the old public names and keep the combined rule disabled by default.
Validation
These are local results, not a claim that fresh GitHub CI or review has completed. No new full-package/full-monorepo test run, website build, or lintdiff corpus comparison is claimed.
Original DELETE promotion description before consolidation (historical)
Original Swagger linter
Checks:
pathsandx-ms-paths.operationId, ignoring absent, empty or non-string values.Deleteprefix before the underscore or after a word-character group prefix.operationIdwhen neither accepted form matches.How the Swagger linter works
The Spectral function checks selected DELETE operation objects and applies serialized-ID regular expressions. It does not inspect SDK metadata or require ARM provider metadata. Its underscore/group-prefix exemptions can accept a Delete-prefixed group with a non-delete method, or ignore a standalone invalid method ID. Those serialization-dependent exemptions are intentionally not copied. Native endpoint selection also avoids warnings on declarations used only for client customization. The source migration evidence documents emitted-name overrides, historical version selection, one-sided projects and compilation failures rather than treating equal totals as proof of equivalence.
Source TypeSpec lintdiff rule
DeleteInOperationName; canonical slug:delete-in-operation-name.tsp-lintdiff-local-linter/delete-in-operation-name.Azure/typespec-azure; source branch:feature/lintdiff-delete-in-operation-name.a0b5e8d9a9edee978219c2490c72eac7cc79845b; development GitHub review clean after two Balanced rounds on this final pushed commit.C:\dev\worktrees\lintdiff-delete-in-operation-name; clean, no uncommitted source changes.The source was assumed done for this promotion run and was not modified. It checks authored names on concrete HTTP service endpoints, DELETE only, with a case-insensitive
deleteprefix and warning targets on the original operation. Initial source commit8af7a71258c41b8ca10950023c62cc4633bb24fcis historical; the reviewed source above additionally fixes the harness's stale coverage-kind assertion without changing production behavior.Destination analysis
The agent selected
@azure-tools/typespec-client-generator-corebecause the approved naming-family promotion contract governs common SDK method names. Existinguse-create-for-putand supportedgetLibraryName(..., AllScopes)establish that ownership and implementation pattern. The new public name isuse-delete-for-delete.Bothapplicability and compiler/HTTP-only authored-name semantics make Azure Core a plausible authored-domain alternative. Core'suse-standard-namesalready checks authored DELETE names in data-plane rulesets, but not the common SDK override domain. An SDK resolver must not introduce TCGC dependencies into Core or ARM. ARM fixture origin alone does not establish ARM-only semantics; this rule requires neither provider metadata nor ARM helpers in production. Existing TCGCget-operation-nameis GET-specific and is not equivalent DELETE coverage.How the promoted TypeSpec linter works
The root listener uses
getAllHttpServicesand checks concrete service operations with verbdelete. A TCGC context created with{ mutateNamespace: false }resolves the common SDK name usinggetLibraryName(context, operation, AllScopes). This honors unscoped client names, exact-name normalization and supported friendly-name fallback, independently of positive language-specific overrides and explicit OpenAPI operation IDs. No emitter or API-version projection is selected, and historical renamed names are not reconstructed.The prefix remains case-insensitive, severity remains warning and each finding targets the original operation, including when an override supplies the displayed SDK name. Group names do not mask an invalid method name. The authorized adaptation changes only the authored-name domain to common SDK names; source selection, DELETE condition, prefix policy and diagnostic targets remain intact. There is no hand-rolled resolver, serialized-reference inference, namespace mutation or emitter coupling.
The
client-sdkruleset registers the new rule with plainfalse; ARM/data-plane rulesets and C# default rules are unchanged. Separate Chronus entries classify destination availability asfeatureand disabled-only ruleset registration asinternal.Fixture-to-native test mapping
it("reports a customized standard ARM delete endpoint")it("accepts a standard ARM delete endpoint")it("reports an invalid HTTP SDK name")it("accepts a valid HTTP SDK name")it("accepts a common SDK name override")it("reports an invalid unscoped client name on the authored operation")it("reports an invalid HTTP SDK name")it("does not let a Delete-prefixed group mask an invalid method name")it("reports the published incorrect template alias")it("accepts the published correct template alias")it("accepts the published template client name override")it("accepts the published template suppression")Additional native cases prove SDK override directions, language-specific and mixed names, exact names, friendly fallback, explicit-ID independence, original targets, multiple endpoint findings, non-DELETE controls, case-insensitive prefixes, source endpoint-selection regression, and a common client name on a supported standard ARM deletion alias. Framework-only import exclusion, ordinary inheritance/traversal, uninstantiated-template and suppression tests were not mechanically copied. No validator snapshots, fixtures or corpus payloads are included.
Migration evidence
See source migration.md for focused tests, representative services, full-corpus counts, one-sided project explanations, retained compile failures and uncertainty. Those counts describe the immutable authored-name source, not fresh SDK-domain equivalence or predicted impact. Promotion did not rerun the lintdiff harness or corpus.
Validation
NULignore override: exit 0; generated ignored rule page remains unstaged.ArmResourceDeleteSync<Widget>instead of raw routes. The standalone shared setup includes all imports/usings. Incorrectremoveproduces exactly the target warning; correctdelete, common-name override, and compiler-enabled suppression produce none. Existing generic HTTP behavior tests remain intact.pnpm chronus status: exit 0. Before commit, bothchange addattempts reported no changed package, so the documented fallback created only these two entries.arm client with sub clients, two existing skips; 1663 tests in 102 files, natural exit 1.mise exec -- pnpm --filter @azure-tools/typespec-client-generator-core test --maxWorkers=1: 1661 passed, zero failures, same two skips and 1663 tests/102 files, natural exit 0. Same code, assertions, dependencies and 10000ms test/hook limits; no pool change. Timeout recovered with UNPROVEN original cause. The task-wide diagnostic allowance is exhausted (1/1); the scoped concurrency profile may persist for matching later package validation without granting another retry.--maxWorkers=1profile and unchanged test/hook timeouts. The four added tests account for the population increase.Validation limitations
Required docs regeneration exits 0 with existing documentation warnings for
unnecessary-emitter-optionand unused API@paramtags on untouched APIs; these unrelated warnings were retained, not repaired. The optional repository-wide wrapper was not warranted for this isolated rule and registration change. No local website/dependency-closure build was run; CI's Website job remains authoritative. The original full-suite timeout remains retained evidence, not an environmental diagnosis.Promotion sync policy
The source remains immutable during promotion. A verified source-semantic gap blocks this PR and returns evidence to the owning queue, which alone may authorize its bounded source-repair cycle. Refresh native provenance incrementally only after a new clean reviewed source head; do not repair the source or silently alter its semantics in the promoted copy. The expressly approved common SDK naming adaptation is not source repair.
Review cleanup (October 19, 2026)
Renamed the groups to
HTTP SDK namesandstandard ARM operations, preserving their separate SimpleTester and ARM/standalone setup. Removed the extra DELETE behavior file; focused package-level public-entry coverage retains the throwing AutoRest guard, now outside the PUT behavior suite as well. Removed redundant internal entries; feature and rulesets coverage remain.Published in 50c4b74. Fresh focused validation: 68 tests passed, package production typecheck, root
pnpm format, rootpnpm lint, and diff hygiene passed. The full test TypeScript project retains pre-existing diagnostics (15 before, 15 after); the exact-head baseline comparison found no new diagnostics, accounting explicitly for moved tests and any removed duplicate fixture. This is not a claim that the full test TypeScript project is error-free or that pending CI has passed. These current file-layout/coverage statements supersede earlier descriptions of the removed test files; historical validation remains historical.